package com.lightsh.sensor;

import java.util.List;

import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.util.Log;

public abstract class BaseSensor {
	protected Context mContext;
	protected SensorManager mSensorManager;
	private SensorEventListener mSensorListener;
	private WakeLock mLightLock;
	protected BaseSensor(Context context){
		mContext = context;
		mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
	}
	
	/**
	 * 开始监听传感器数据变化，并锁住cpu
	 * @throws IllegalArgumentException 不支持制定的传感器类型
	 */
	public void start() throws IllegalArgumentException{
		registerListener();
		acquireLock();
	}
	
	/**
	 * 结束监听传感器数据变化，释放cup锁
	 */
	public void end(){
		unregisterListener();
		releaseLock();
	}
	
	/**
	 * @return 需要处理的Sensor类型
	 */
	protected abstract int getSensorType();
	
	/**
	 * @return tag字符值，用来打印log / 锁定cpu等
	 */
	protected abstract String getLogTag();
	
	/**
	 * 传感器状态变更回调
	 */
	protected abstract void onSensorChanged(SensorEvent event);
	
	private void acquireLock(){
		if(mLightLock == null){
			PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
			mLightLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, getLogTag());
		}
		if(!mLightLock.isHeld()){
			logW("acquire PARTIAL_WAKE_LOCK");
			mLightLock.acquire();
		}
	}
	
	private void releaseLock(){
		if(mLightLock != null && mLightLock.isHeld()){
			logW("release PARTIAL_WAKE_LOCK");
			mLightLock.release();
		}
	}
	
	protected void onAccuracyChanged(Sensor sensor, int accuracy){
	}
	
	protected int getSensorRate(){
		return SensorManager.SENSOR_DELAY_UI;
	}
	
	private void registerListener() throws IllegalArgumentException{
		List<Sensor> sensorList = mSensorManager.getSensorList(getSensorType());
		if(sensorList != null && sensorList.size() > 0){
			mSensorListener = new SensorEventListener() {				
				@Override
				public void onSensorChanged(SensorEvent event) {
					BaseSensor.this.onSensorChanged(event);
				}				
				@Override
				public void onAccuracyChanged(Sensor sensor, int accuracy) {
					BaseSensor.this.onAccuracyChanged(sensor, accuracy);
				}
			};
			mSensorManager.registerListener(mSensorListener, sensorList.get(0), getSensorRate());
		}else{
			throw new IllegalArgumentException("Unsupported sensor type : " + getSensorType());
		}
	}
	private void unregisterListener(){
		if(mSensorListener != null){
			mSensorManager.unregisterListener(mSensorListener);
		}
	}
	protected final void logD(String tip){
		Log.d(getLogTag(), tip);
	}
	protected final void logE(String tip){
		Log.e(getLogTag(), tip);
	}
	protected final void logW(String tip){
		Log.w(getLogTag(), tip);
	}
}
